import 'dart:async';
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:sc1_manage_tool/theme/colors.dart';
import 'package:sc1_manage_tool/theme/styles.dart';
import 'package:sc1_manage_tool/util/my_log.dart';

import 'web_rtc_player.dart';

enum RTCPlayState {
  inited,
  connecting,
  connected,
  disconnected,
  error,
}

/// 用来实现webrtc的视频预览
class RtcView extends StatefulWidget {
  const RtcView({
    super.key,
    required this.url,
    required this.localRender,
    required this.selected,
    this.onRefresh,
    this.onConnected,
    this.onDisconnected,
    required this.index,
  });

  /// webrtc地址
  final String url;

  /// 渲染视频
  final RTCVideoRenderer localRender;

  /// 是否被选中
  final bool selected;

  /// 在预览列表中的下标
  final int index;

  /// 刷新回调
  final VoidCallback? onRefresh;

  /// rtc连接时的回调
  final VoidCallback? onConnected;

  /// rtc断开连接的回调
  final VoidCallback? onDisconnected;

  @override
  State<RtcView> createState() => _RtcViewState();
}

class _RtcViewState extends State<RtcView> {
  String tag = "_RtcViewState";
  bool debug = true;
  late WebRTCPlayer _rtcPlayer;

  RTCPlayState _playState = RTCPlayState.inited;

  /// 定时获取音量
  Timer? _timer;

  @override
  void initState() {
    debugLog("initState ${widget.url}");
    _rtcPlayer = WebRTCPlayer(
      onLocalConnectionState: onLocalConnectionState,
      onSignalingState: onSignalingState,
    );
    // Helper.setAndroidAudioConfiguration(
    //   AndroidAudioConfiguration(
    //     androidAudioMode: AndroidAudioMode.normal,
    //     androidAudioFocusMode: AndroidAudioFocusMode.gain,
    //   ),
    // );

    // _remoteConnection?.addTrack(track);
    _rtcPlayer.initState();
    autoPlay();

    super.initState();
  }

  @override
  void didChangeDependencies() {
    debugLog("didChangeDependencies");
    super.didChangeDependencies();
  }

  @override
  void didUpdateWidget(covariant RtcView oldWidget) {
    debugLog(
        "didUpdateWidget -- oldWidget.url:${oldWidget.url} url:${widget.url}\n"
        "widget.index:${widget.index} oldWidget.index:${oldWidget.index}");

    if (oldWidget.url != widget.url) {
      debugLog("play new url ");
      playVideo();
    }

    // var mute = context.read<TopVideoModel>().mute;
    var mute = false;
    debugLog("mute:$mute");
    if (widget.selected && !mute) {
      getRTCInfo();
    } else {
      debugLog("index:${widget.index} cancel timer");
      _timer?.cancel();
    }

    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    debugLog("dispose");
    _timer?.cancel();
    _cleanUp();
    super.dispose();
  }

  Future<void> autoPlay() async {
    await widget.localRender
        .initialize()
        .onError((error, stackTrace) => MyLog.e(tag, "$error"));

    // Render stream when got remote stream.
    _rtcPlayer.onRemoteStream = (MediaStream stream) {
      debugLog("onRemoteStream");
      // @remark It's very important to use setState to set the srcObject and notify render.
      if (mounted) {
        setState(() {
          widget.localRender.srcObject = stream;
        });
      }

      //扬声器播放声音
      Future.delayed(const Duration(seconds: 1),
          () => Helper.setSpeakerphoneOnButPreferBluetooth());
    };
    // Auto start play WebRTC streaming.
    playVideo();
  }

  void playVideo() async {
    try {
      _rtcPlayer.play(widget.url)
        ..then((value) async {})
        ..onError((error, stackTrace) => onPlayVideoError(error));
    } catch (e) {
      MyLog.e(tag, e.toString());
    }
  }

  //TODO 异常处理
  void onPlayVideoError(Object? error) {
    MyLog.e(tag, "error: $error");
    //发生异常
    _playState = RTCPlayState.error;
    if (mounted) {
      setState(() {});
    }
  }

  void setVolume(double volume, MediaStream stream) {
    Helper.setVolume(volume, stream.getAudioTracks()[0]);
  }

  void getMediaInfo() async {
    var mediaDevicesList = await navigator.mediaDevices.enumerateDevices();
    for (var deviceInfo in mediaDevicesList) {
      if (deviceInfo.kind == "audiooutput") {
        //日志打印如下
        //----DeviceInfo Speakerphone:speaker
        //----DeviceInfo Earpiece:earpiece
        debugLog("----DeviceInfo ${deviceInfo.label}:${deviceInfo.deviceId}");
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return _playState == RTCPlayState.connected
        ? RTCVideoView(
            widget.localRender,
            objectFit: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
            placeholderBuilder: _playState == RTCPlayState.connected
                ? null
                : (context) => RTCViewPlaceholder(
                      state: _playState,
                      onRefresh: onRefresh,
                    ),
          )
        : RTCViewPlaceholder(
            state: _playState,
            onRefresh: onRefresh,
          );
  }

  /// RTC对等连接状态回调
  void onLocalConnectionState(RTCPeerConnectionState state) {
    debugLog("onLocalConnectionState:$state");
    switch (state) {
      case RTCPeerConnectionState.RTCPeerConnectionStateConnecting:
        break;
      case RTCPeerConnectionState.RTCPeerConnectionStateConnected:
        // context.read<Cameras>().renders[widget.index] = widget.localRender;
        //初始化声音音量，根据选中状态和静音按钮状态来控制
        // var mute = context.read<TopVideoModel>().mute;
        // double volume = widget.selected && !mute ? 1.0 : 0;
        // debugLog("volume:$volume");
        // if (widget.localRender.srcObject != null) {
        //   setVolume(volume, widget.localRender.srcObject!);
        // }

        _playState = RTCPlayState.connected;
        // if (widget.selected && !mute) {
        //   getRTCInfo();
        // }

        onConnected();
        break;
      case RTCPeerConnectionState.RTCPeerConnectionStateFailed:
      case RTCPeerConnectionState.RTCPeerConnectionStateClosed:
      case RTCPeerConnectionState.RTCPeerConnectionStateDisconnected:
        _playState = RTCPlayState.disconnected;
        stopTimer();
        onDisconnected();
        break;
      default:
        break;
    }
    if (mounted) {
      setState(() {});
    }
  }

  void onSignalingState(RTCSignalingState state) {
    debugLog("onSignalingState: $state");
    switch (state) {
      case RTCSignalingState.RTCSignalingStateStable:
      // TODO: Handle this case.
      case RTCSignalingState.RTCSignalingStateHaveLocalOffer:
      // TODO: Handle this case.
      case RTCSignalingState.RTCSignalingStateHaveRemoteOffer:
      // TODO: Handle this case.
      case RTCSignalingState.RTCSignalingStateHaveLocalPrAnswer:
      // TODO: Handle this case.
      case RTCSignalingState.RTCSignalingStateHaveRemotePrAnswer:
      // TODO: Handle this case.
      case RTCSignalingState.RTCSignalingStateClosed:
      // TODO: Handle this case.
    }
  }

  void onConnected() async {
    debugLog("onConnected");
    widget.onConnected?.call();
  }

  void onDisconnected() {
    debugLog("onDisconnected");
    widget.onDisconnected?.call();
  }

  void onRefresh() async {
    debugLog("onRefresh");
    // var connectivityResult = await Connectivity().checkConnectivity();
    // if (connectivityResult != ConnectivityResult.wifi) {
    //   showConnectWifiSnackBar(context);
    //   return;
    // }
    widget.onRefresh?.call();
  }

  void _cleanUp() {
    // widget.localRenderer.srcObject = null;
    widget.localRender.dispose();
    _rtcPlayer.dispose();
  }

  void stopTimer() {
    _timer?.cancel();
  }

  void getRTCInfo() async {
    if (_timer != null && _timer!.isActive && !mounted) {
      return;
    }
    debugLog("getRTCInfo ${widget.index}");
    // var audioVolumePercent = context.read<AudioVolumePercent>();
    // await Future.delayed(const Duration(seconds: 2));
    // 1秒10次
    _timer = Timer.periodic(const Duration(milliseconds: 100), (timer) async {
      try {
        List<StatsReport>? list =
            await _rtcPlayer.localPeerConnection?.getStats();

        if (list != null) {
          // MyLog.w(tag, "*******************");
          // MyLog.w(tag, "listLength:${list.length}");

          for (var value in list) {
            if (value.values.containsKey("audioLevel")) {
              var audioLevel = value.values["audioLevel"];
              // MyLog.w(tag, "audioLevel:$audioLevel");
              var decibel = calculateDecibel(audioLevel);

              //-60dB ~ 0dB
              //正常语音：正常的人类语音通常在约 -20 dB（较安静的谈话）到约 -6 dB（正常对话）之间。
              //
              // 音乐：音乐的分贝范围可以相当广泛，从极安静的部分（如古典音乐中的安静段落）约 -40 dB 到非常高的音量（如摇滚音乐的演奏部分）约 0 dB 以上。
              //
              // 电视和广播：电视节目和广播通常在 -24 dB 到 -10 dB 之间，但音量可能会根据节目内容和广告而有所不同。
              //
              // 电影：电影的分贝范围通常很广，从非常安静的部分（如悬疑片的紧张场景）约 -30 dB 到爆炸和特效场景中的峰值，可能超过 0 dB。
              double percent = 0;
              if (decibel == double.infinity) {
                percent = 1;
              } else if (decibel == double.negativeInfinity) {
                percent = 0;
              } else {
                percent = decibel / -60;
              }
              // MyLog.w(tag, "dB: $decibel  percent:$percent");
              // audioVolumePercent.update(percent);
            }
          }
          // MyLog.w(tag, "++++++++++++++++++++++++++++++++++++++++++++++++");

          //   for (var value in list) {
          //     if (value.track!.kind == 'audio') {
          //       List<StatsReport> list2 = await value.getStats();
          //
          //       for (var value2 in list2) {
          //         MyLog.w(tag, "**************\n${value2.values.toString()}");
          //       }
          //     }
          //   }
        }
      } catch (e) {
        timer.cancel();
      }
    });
  }

  double calculateDecibel(double audioLevel) {
    // 如果音频级别为0，则分贝值为负无穷大
    if (audioLevel <= 0) {
      return double.negativeInfinity;
    }

    double decibel = 20 * log(audioLevel) / log(10);
    return decibel;
  }

  void debugLog(String msg) {
    if (debug) {
      MyLog.i(tag, msg);
    }
  }
}

class RTCViewPlaceholder extends StatefulWidget {
  const RTCViewPlaceholder({
    super.key,
    required this.state,
    this.onRefresh,
  });

  final RTCPlayState state;
  final VoidCallback? onRefresh;

  @override
  State<RTCViewPlaceholder> createState() => _RTCViewPlaceholderState();
}

class _RTCViewPlaceholderState extends State<RTCViewPlaceholder> {
  String tag = "_RTCViewPlaceholderState";
  bool debug = false;

  @override
  void initState() {
    debugLog("initState");
    super.initState();
  }

  // Widget _buildError() => Column(
  //       mainAxisAlignment: MainAxisAlignment.center,
  //       children: [
  //         Icon(
  //           Icons.error,
  //           color: Colors.white,
  //           size: 15.w,
  //         ),
  //         MySizedBox.h8,
  //         Text(
  //           MyLocalizations.of(context).error,
  //           style: TextStyle(
  //             fontSize: 12.sp,
  //             color: MyColor.white,
  //           ),
  //         ),
  //       ],
  //     );

  Widget _buildIndicate() => Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          SizedBox(
            width: 15.w,
            height: 15.w,
            child: CupertinoActivityIndicator(
              color: Colors.white,
              radius: 7.5.r,
            ),
          ),
          MySizedBox.h8,
          Text(
            "加载中...",
            style: TextStyle(
              fontSize: 10.sp,
              color: MyColor.white,
            ),
          ),
        ],
      );

  Widget _buildRefresh() => InkWell(
        borderRadius: BorderRadius.only(
          topLeft: Radius.circular(12.r),
          topRight: Radius.circular(12.r),
        ),
        child: Container(
          // width: 25.w,
          // height: 40.h,
          alignment: Alignment.center,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Icon(
                Icons.refresh,
                color: MyColor.white,
                size: 20.w,
              ),
              MySizedBox.h4,
              Text(
                "刷新",
                style: TextStyle(
                  fontSize: 12.sp,
                  color: MyColor.white,
                ),
                textAlign: TextAlign.center,
              ),
            ],
          ),
        ),
        onTap: () {
          debugLog("点击了刷新");
          widget.onRefresh == null ? null : widget.onRefresh!();
        },
      );

  Widget _buildHolder() {
    debugLog("_buildHolder state:${widget.state}");
    switch (widget.state) {
      case RTCPlayState.error:
        return _buildRefresh();
      case RTCPlayState.disconnected:
        return _buildRefresh();
      case RTCPlayState.connected:
        return const SizedBox.shrink();
      default:
        return _buildIndicate();
    }
  }

  @override
  Widget build(BuildContext context) {
    debugLog("state ${widget.state}");
    switch (widget.state) {
      case RTCPlayState.connected:
        return const Opacity(opacity: 0);
      default:
        break;
    }
    return Center(
      child: _buildHolder(),
    );
  }

  void debugLog(String msg) {
    if (debug) {
      MyLog.i(tag, msg);
    }
  }
}
